<?php

/**
 * 全局函数配置
 */

/**
 * 首字母头像
 * @param $text
 * @return string
 */
if (!function_exists('letter_avatar')) {
    function letter_avatar($text) {
        // 1. 计算哈希值确定色调（保持原逻辑，确保相同昵称生成相同颜色）
        $total = unpack('L', hash('adler32', $text, true))[1];
        $hue = $total % 360;
        $h = $hue / 360;
        $s = 0.3; // 固定饱和度
        $v = 0.9; // 固定明度

        // 2. 合并HSV转RGB逻辑（内嵌原hsv2rgb功能）
        $i = floor($h * 6);
        $f = $h * 6 - $i;
        $p = $v * (1 - $s);
        $q = $v * (1 - $f * $s);
        $t = $v * (1 - (1 - $f) * $s);

        switch ($i % 6) {
            case 0: list($r, $g, $b) = [$v, $t, $p]; break;
            case 1: list($r, $g, $b) = [$q, $v, $p]; break;
            case 2: list($r, $g, $b) = [$p, $v, $t]; break;
            case 3: list($r, $g, $b) = [$p, $q, $v]; break;
            case 4: list($r, $g, $b) = [$t, $p, $v]; break;
            case 5: list($r, $g, $b) = [$v, $p, $q]; break;
        }
        $r = floor($r * 255);
        $g = floor($g * 255);
        $b = floor($b * 255);

        // 3. 生成SVG并转为base64
        $bg = "rgb({$r},{$g},{$b})";
        $color = "#ffffff";
        $first = mb_strtoupper(mb_substr($text, 0, 1)); // 提取首字母并转为大写
        $svg = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="100" width="100">
            <rect fill="' . $bg . '" x="0" y="0" width="100" height="100"></rect>
            <text x="50" y="50" font-size="50" fill="' . $color . '" text-anchor="middle" dominant-baseline="central">' . $first . '</text>
        </svg>';
        return 'data:image/svg+xml;base64,' . base64_encode($svg);
    }
}

/**
 * 多行输入框回车换行
 * @param string $str
 * @return string mixed
 */
if (!function_exists('line_feed')) {
    function line_feed(string $str): string
    {
        return str_replace("\n", "<br />", $str ?? '');
    }
}

/**
 * 超出字符省略
 * @param $value
 * @param int $limit
 * @param string $end
 * @return mixed|string
 */
if (!function_exists('str_limit')) {
    function str_limit($value, int $limit = 100, string $end = '...'): mixed
    {
        if (mb_strwidth($value, 'UTF-8') <= $limit) {
            return $value;
        }
        return rtrim(mb_strimwidth($value, 0, $limit, '', 'UTF-8')) . $end;
    }
}

/**
 * 返回输入数组中某个单一列的值
 * @Author PandaEyes
 * @email joeyoung0314@qq.com
 * @PHP_VERSION >=7.3
 * @param array $array 多维数组
 * @param string|null $column_keys 可以是索引数组的列的整数索引，或者是关联数组的列的字符串键值,该参数也可以是 NULL，此时将返回整个数组,配合index_key使用，注意，与array_column不同的是，此处可以返回多列，可用','分割
 * @param string|null $index_key 取出数组中这一列当做返回数组的索引 注意，与array_column不同的是，此处将不会去重，而是将所有符合的数组编排到同一键中
 * @return array
 */
if (!function_exists('array_columns')) {
    function array_columns(array $array, string $column_keys = null, string $index_key = null): array
    {
        $result = [];
        $keys   = isset($column_keys) ? explode(',', $column_keys) : [];

        if ($array) {
            foreach ($array as $item) {
                // 指定返回列
                if ($keys) {
                    $tmp = [];
                    foreach ($keys as $key) {
                        $tmp[$key] = $item[$key];
                    }
                } else {
                    $tmp = $item;
                }
                // 指定索引列
                if (isset($index_key)) {
                    $result[$item[$index_key]][] = $tmp;
                } else {
                    $result[] = $tmp;
                }

            }
        }
        return $result;
    }
}

/**
 * 根据日期返回周几
 * @param $date
 * @return mixed|string
 */
if (!function_exists('get_week')) {
    function get_week($date): mixed
    {
        $week = date('N', strtotime($date));
        $data = [
            '1' => '星期一',
            '2' => '星期二',
            '3' => '星期三',
            '4' => '星期四',
            '5' => '星期五',
            '6' => '星期六',
            '7' => '星期日',
        ];
        $week = $data[$week];
        return $week;
    }
}

/**
 * 根据日期返回周几
 * @param $date
 * @return mixed|string
 */
if (!function_exists('date_chinese')) {
    function date_chinese(string $date)
    {
        $time = strtotime($date);

        $yearChinese  = ['〇', '一', '二', '三', '四', '五', '六', '七', '八', '九'];
        $monthChinese = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '十一', '十二'];
        $dayTenChinese = ['十', '廿', '三'];
        $dayOneChinese  = ['十', '一', '二', '三', '四', '五', '六', '七', '八', '九'];

        $years  = preg_split('/(?<!^)(?!$)/u', date('Y', $time));
        $months = date('m', $time);
        $days   = date('d', $time);

        // 将时间戳转换为中文大写年份
        $chineseYear = '';
        foreach ($years as $year) {
            $chineseYear .= $yearChinese[(int)$year];
        }

        // 将时间戳转换为中文大写月份
        $chineseMonth = $monthChinese[$months - 1];

        // 将时间戳转换为中文大写日期
        $chineseDay = '';
        if ($days > 10) {
            $days = preg_split('/(?<!^)(?!$)/u', $days);
            $chineseDay = "{$dayTenChinese[$days[0]-1]}{$dayOneChinese[$days[1]]}";
        }else{
            $chineseDay = $dayOneChinese[(int)$days];
        }

        return "{$chineseYear}年{$chineseMonth}月{$chineseDay}日";
    }
}

/**
 * 根据时间返回当前所处时分
 * @param $date
 * @return string
 */
if (!function_exists('hour_type')) {
    function hour_type(string $time = '')
    {
        $time = !empty($time) ? $time : time();
        $time = date('H:i', $time);
        if ($time >= '12:00' && $time < '05:00') {
            $data = 'late_night';
        } elseif ($time >= '05:00' && $time < '12:00') {
            $data = 'am';
        } elseif ($time >= '12:00' && $time < '19:00') {
            $data = 'pm';
        } else {
            $data = 'night';
        }
        return $data;
    }
}

/**
 * 根据时间返回当前所处时分 中文
 * @param $date
 * @return string
 */
if (!function_exists('hour_chinese')) {
    function hour_chinese(string $time = '')
    {
        $time = !empty($time) ? $time : time();
        $type = hour_type($time);
        return match ($type) {
            'late_night' => '深夜',
            'am' => '上午',
            'pm' => '下午',
            'night' => '晚上',
        };
    }
}

if (!function_exists('base64_encode_str')) {
    function base64_encode_str($input)
    {
        return str_replace('=', '', strtr(base64_encode($input), '+/', '-_'));
    }
}

if (!function_exists('base64_decode_str')) {
    function base64_decode_str($input)
    {
        $remainder = strlen($input) % 4;
        if ($remainder) {
            $addlen = 4 - $remainder;
            $input  .= str_repeat('=', $addlen);
        }
        return base64_decode(strtr($input, '-_', '+/'));
    }
}

/**
 * 自动转换文件大小
 * @param $filesize
 * @return string
 */
if (!function_exists('file_size')) {
    function file_size($filesize): string
    {
        if ($filesize >= 1073741824) {
            $filesize = round($filesize / 1073741824 * 100) / 100 . 'GB';
        } elseif ($filesize >= 1048576) {
            $filesize = round($filesize / 1048576 * 100) / 100 . 'MB';
        } elseif ($filesize >= 1024) {
            $filesize = round($filesize / 1024 * 100) / 100 . 'KB';
        } else {
            $filesize = $filesize . 'bytes';
        }
        return $filesize;
    }
}

/**
 * 毫秒时间戳
 * @return int
 */
if (!function_exists('ms_time')) {
    function ms_time(): int
    {
        list($ms, $sec) = explode(' ', microtime());
        return intval((floatval($ms) + floatval($sec)) * 1000);
    }
}

/**
 * 将秒时间转换具体时间:秒转天时分秒
 * @return bool|string
 */
if (!function_exists('time_ext')) {
    function time_ext(int $seconds): bool|string
    {
        $d = floor($seconds / (3600*24));
        $h = floor(($seconds % (3600*24)) / 3600);
        $m = floor((($seconds % (3600*24)) % 3600) / 60);
        if($d>'0'){
            $time = "{$d}天{$h}小时{$m}分";
        }else{
            if($h!='0'){
                $time = "{$h}小时{$m}分";
            }else{
                $time = "{$m}分钟";
            }
        }
        return $time;
    }
}

// 校验身份证号
if (!function_exists('check_id_card')) {
    function check_id_card($idCard) {
        // 长度校验
        if (strlen($idCard) != 18) {
            return false;
        }

        // 基本格式校验
        if (!preg_match('/^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[1-2]\d|3[0-1])\d{3}[\dXx]$/', $idCard)) {
            return false;
        }

        // 校验码验证
        $factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
        $verifyCodes = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
        $sum = 0;

        for ($i = 0; $i < 17; $i++) {
            $sum += $idCard[$i] * $factor[$i];
        }

        $mod = $sum % 11;
        $verifyCode = $verifyCodes[$mod];

        return strtoupper($idCard[17]) == $verifyCode;
    }
}

// 获取身份证号信息
if (!function_exists('get_id_card_info')) {
    function get_id_card_info($idCard) {
        if (!check_id_card($idCard)) {
            return false;
        }

        $areaCode = substr($idCard, 0, 6);
        $birthYear = substr($idCard, 6, 4);
        $birthMonth = substr($idCard, 10, 2);
        $birthDay = substr($idCard, 12, 2);
        $genderDigit = $idCard[16];
        $gender = ($genderDigit % 2 == 0) ? '女' : '男';

        return [
            'area_code' => $areaCode,
            'birthday' => $birthYear . '-' . $birthMonth . '-' . $birthDay,
            'gender' => $gender,
            'age' => date('Y') - $birthYear
        ];
    }
}

/**
 * 将阿拉伯数字金额转换为中文大写金额
 * @param float $amount 金额（支持两位小数）
 * @return string 中文大写金额
 */
if (!function_exists('amount_to_chinese')) {
    function amount_to_chinese($amount) {
        // 定义数字对应的中文
        $cnNumbers = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
        $cnUnits = ['', '拾', '佰', '仟', '万', '拾', '佰', '仟', '亿'];
        $cnDecimals = ['角', '分'];

        // 处理负数
        if ($amount < 0) {
            return '负' . amount_to_chinese(abs($amount));
        }

        // 拆分整数和小数部分
        $amountStr = number_format($amount, 2, '.', '');
        list($integerPart, $decimalPart) = explode('.', $amountStr);

        $result = '';

        // 处理整数部分
        $integerLen = strlen($integerPart);
        for ($i = 0; $i < $integerLen; $i++) {
            $num = $integerPart[$i];
            $unit = $cnUnits[$integerLen - $i - 1];
            if ($num != '0') {
                $result .= $cnNumbers[$num] . $unit;
            } else {
                // 处理连续的零（如 1001 → 壹仟零壹）
                if ($i < $integerLen - 1 && $integerPart[$i + 1] != '0') {
                    $result .= $cnNumbers[$num];
                }
            }
        }
        if ($integerPart != '0') {
            $result .= '元';
        }

        // 处理小数部分
        $decimalStr = '';
        for ($i = 0; $i < 2; $i++) {
            $num = $decimalPart[$i];
            if ($num != '0') {
                $decimalStr .= $cnNumbers[$num] . $cnDecimals[$i];
            }
        }
        $result .= $decimalStr ?: '整';

        // 处理纯零的情况
        if ($result == '') {
            $result = $cnNumbers[0] . '元整';
        }

        return $result;
    }
}